/*
 * @Author: 0x9DEFA478
 * @Date: 2021-09-06 20:25:45
 * @LastEditTime: 2021-09-06 21:31:01
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "H_FFT.h"




void H_FFT_ReverseData_Single(void* v,void* Src,int NumOfPoint){
  int i;
  
  float* src;
	float *src0;
	float *src1;
  float t_f;
	unsigned short re_i;
	unsigned short* BitReverseTable;

  src=Src;

  BitReverseTable=((H_FFT*)v)->BitReverseTable;

  for(i = 0;i<NumOfPoint;i++){
    re_i = BitReverseTable[0];
    if(re_i>i) {

      src0=&src[i*2];
      src1=&src[re_i*2];
      
      t_f=src0[0];
      src0[0]=src1[0];
      src1[0]=t_f;

      t_f=src0[1];
      src0[1]=src1[1];
      src1[1]=t_f;
    }

    BitReverseTable=&BitReverseTable[1];
  }
}

void H_FFT_ReverseData_Double(void* v,void* Src,int NumOfPoint){
  int i;
  
  double* src;
	double *src0;
	double *src1;
  double t_f;
	unsigned short re_i;
	unsigned short* BitReverseTable;

  src=Src;

  BitReverseTable=((H_FFT*)v)->BitReverseTable;

  for(i = 0;i<NumOfPoint;i++){
    re_i = BitReverseTable[0];
    if(re_i>i) {

      src0=&src[i*2];
      src1=&src[re_i*2];
      
      t_f=src0[0];
      src0[0]=src1[0];
      src1[0]=t_f;

      t_f=src0[1];
      src0[1]=src1[1];
      src1[1]=t_f;
    }

    BitReverseTable=&BitReverseTable[1];
  }
}





/**
 * @brief 计算基二FFT 单精度
 * @param h_fft h_fft对象
 * @param Src 源数据 计算结果也存放在此处
 * @return 无
 */
void H_FFT_cfftRadix2_Single(H_FFT* h_fft,float* Src){

  float* W;

  float* ArrFloat_t;

  //2^L
  int x2expL;
  int L;
  int L_m;
  int g;
  int g_m;
  int r;

  float* x0_ptr;
  float x0_real;
  float x0_image;
  float* x1_ptr;
  float x1_real;
  float x1_image;

  float t0_real;
  float t0_image;

  float W1_real;
  float W1_image;

  int NumOfPoint;
  int NumOfPointOf2;


  if(h_fft->Type!=vH_FFT_Type_Single){
    return;
  }
  
  NumOfPoint=h_fft->NumOfPoint;

  h_fft->ReverseData(h_fft,Src,NumOfPoint);
  
  NumOfPointOf2=NumOfPoint>>1;
  W=h_fft->W;

  x2expL = 1;
  L_m=h_fft->NumOfPointBits;
  //蝶形运算 计算每一级
  for(L=0; L<L_m; L++){
    //蝶形一组的运算 循环每一组
    g_m=NumOfPointOf2/x2expL;
    for(g=0;g<g_m;g++){
      //每次循环计算一个基二蝶形运算
      for(r=0;r<x2expL;r++){
        x0_ptr=&Src[(g*2*x2expL+r)*2];
        x1_ptr=&x0_ptr[x2expL*2];
        x0_real=x0_ptr[0];
        x0_image=x0_ptr[1];
        x1_real=x1_ptr[0];
        x1_image=x1_ptr[1];

        ArrFloat_t=&W[r*(NumOfPointOf2/x2expL)*2];
        W1_real=ArrFloat_t[0];
        W1_image=ArrFloat_t[1];

        t0_real=x1_real*W1_real-x1_image*W1_image;
        t0_image=x1_real*W1_image+x1_image*W1_real;

        x0_ptr[0]=x0_real+t0_real;
        x0_ptr[1]=x0_image+t0_image;
        x1_ptr[0]=x0_real-t0_real;
        x1_ptr[1]=x0_image-t0_image;
      }
    }
    x2expL*=2;
  }
}

/**
 * @brief 计算基二FFT 双精度
 * @param h_fft h_fft对象
 * @param Src 源数据 计算结果也存放在此处
 * @return 无
 */
void H_FFT_cfftRadix2_Double(H_FFT* h_fft,double* Src){

  double* W;

  double* ArrDouble_t;

  //2^L
  int x2expL;
  int L;
  int L_m;
  int g;
  int g_m;
  int r;

  double* x0_ptr;
  double x0_real;
  double x0_image;
  double* x1_ptr;
  double x1_real;
  double x1_image;

  double t0_real;
  double t0_image;

  double W1_real;
  double W1_image;

  int NumOfPoint;
  int NumOfPointOf2;


  if(h_fft->Type!=vH_FFT_Type_Double){
    return;
  }
  
  NumOfPoint=h_fft->NumOfPoint;

  h_fft->ReverseData(h_fft,Src,NumOfPoint);
  
  NumOfPointOf2=NumOfPoint>>1;
  W=h_fft->W;

  x2expL = 1;
  L_m=h_fft->NumOfPointBits;
  //蝶形运算 计算每一级
  for(L=0; L<L_m; L++){
    //蝶形一组的运算 循环每一组
    g_m=NumOfPointOf2/x2expL;
    for(g=0;g<g_m;g++){
      //每次循环计算一个基二蝶形运算
      for(r=0;r<x2expL;r++){
        x0_ptr=&Src[(g*2*x2expL+r)*2];
        x1_ptr=&x0_ptr[x2expL*2];
        x0_real=x0_ptr[0];
        x0_image=x0_ptr[1];
        x1_real=x1_ptr[0];
        x1_image=x1_ptr[1];

        ArrDouble_t=&W[r*(NumOfPointOf2/x2expL)*2];
        W1_real=ArrDouble_t[0];
        W1_image=ArrDouble_t[1];

        t0_real=x1_real*W1_real-x1_image*W1_image;
        t0_image=x1_real*W1_image+x1_image*W1_real;

        x0_ptr[0]=x0_real+t0_real;
        x0_ptr[1]=x0_image+t0_image;
        x1_ptr[0]=x0_real-t0_real;
        x1_ptr[1]=x0_image-t0_image;
      }
    }
    x2expL*=2;
  }
}

/**
 * @brief 计算基四FFT 单精度
 * @param h_fft h_fft对象
 * @param Src 源数据 计算结果也存放在此处
 * @return 无
 */
void H_FFT_cfftRadix4_Single(H_FFT *h_fft,float *Src){

  float* W;

  float* ArrFloat_t;

  //4^L
  int x4expL;
  int L;
  int L_m;
  int g;
  int g_m;
  int r;

  float* x0_ptr;
  float* x1_ptr;
  float* x2_ptr;
  float* x3_ptr;
  float x0_real;
  float x0_image;
  float x1_real;
  float x1_image;
  float x2_real;
  float x2_image;
  float x3_real;
  float x3_image;

  float t0_real;
  float t0_image;
  float t1_real;
  float t1_image;

  float W1_real;
  float W1_image;
  float W2_real;
  float W2_image;
  float W3_real;
  float W3_image;

  int NumOfPoint;
  int NumOfPointOf4;
  
  //为(r*(NumOfPointOf4/x4expL))*2
  int r_NumOfPointOf4__x4expL_2;


  if(h_fft->Type!=vH_FFT_Type_Single){
    return;
  }
  if(h_fft->Radix4_Enable==0){
    return;
  }
  
  NumOfPoint=h_fft->NumOfPoint;

  h_fft->ReverseData(h_fft,Src,NumOfPoint);

  NumOfPointOf4=NumOfPoint>>2;
  W=h_fft->W;
  

  x4expL=1;
  //蝶形运算 计算每一级
  L_m=h_fft->NumOfPointBits/2;
  for(L=0; L<L_m; L++){
    //蝶形一组的运算 循环每一组
    g_m=NumOfPointOf4/x4expL;
    for(g=0; g<g_m; g++){
      //每次循环计算一个基四蝶形运算
      for(r=0; r<x4expL; r++){

        //获取蝶形运算需要的源数据
        x0_ptr=&Src[(g*4*x4expL+r)*2];
        x2_ptr=&x0_ptr[x4expL*2];
        x1_ptr=&x2_ptr[x4expL*2];
        x3_ptr=&x1_ptr[x4expL*2];
        x0_real=x0_ptr[0];
        x0_image=x0_ptr[1];
        x1_real=x1_ptr[0];
        x1_image=x1_ptr[1];
        x2_real=x2_ptr[0];
        x2_image=x2_ptr[1];
        x3_real=x3_ptr[0];
        x3_image=x3_ptr[1];



        //获取旋转因数 W
        r_NumOfPointOf4__x4expL_2=(r*(NumOfPointOf4/x4expL))*2;
        ArrFloat_t=&W[r_NumOfPointOf4__x4expL_2];
        W1_real=ArrFloat_t[0];
        W1_image=ArrFloat_t[1];
        ArrFloat_t=&ArrFloat_t[r_NumOfPointOf4__x4expL_2];
        W2_real=ArrFloat_t[0];
        W2_image=ArrFloat_t[1];
        ArrFloat_t=&ArrFloat_t[r_NumOfPointOf4__x4expL_2];
        W3_real=ArrFloat_t[0];
        W3_image=ArrFloat_t[1];

        //计算 x1*W
        t0_real=x1_real*W1_real-x1_image*W1_image;
        t0_image=x1_real*W1_image+x1_image*W1_real;
        x1_real=t0_real;
        x1_image=t0_image;

        //计算 x2*W
        t0_real=x2_real*W2_real-x2_image*W2_image;
        t0_image=x2_real*W2_image+x2_image*W2_real;
        x2_real=t0_real;
        x2_image=t0_image;

        //计算 x3*W
        t0_real=x3_real*W3_real-x3_image*W3_image;
        t0_image=x3_real*W3_image+x3_image*W3_real;
        x3_real=t0_real;
        x3_image=t0_image;

        //计算中间值 U(0)->t0 U(2)->t1
        t0_real=x0_real+x2_real;
        t0_image=x0_image+x2_image;
        t1_real=x1_real+x3_real;
        t1_image=x1_image+x3_image;
        
        //计算蝶形结果 X(0)->Src[(g*4*x4expL+r)*2] X(1)->Src[(g*4*x4expL+r+x4expL*2)*2]
        x0_ptr[0]=t0_real+t1_real;
        x0_ptr[1]=t0_image+t1_image;
        x1_ptr[0]=t0_real-t1_real;
        x1_ptr[1]=t0_image-t1_image;

        //计算中间值 U(3)->t1
        t1_real=x1_image-x3_image;
        t1_image=x3_real-x1_real;

        //计算中间值 U(1)->t0
        t0_real=x0_real-x2_real;
        t0_image=x0_image-x2_image;

        //计算蝶形结果 X(2)->Src[(g*4*x4expL+r+x4expL)*2] X(3)->Src[(g*4*x4expL+r+x4expL*3)*2]
        x2_ptr[0]=t0_real+t1_real;
        x2_ptr[1]=t0_image+t1_image;
        x3_ptr[0]=t0_real-t1_real;
        x3_ptr[1]=t0_image-t1_image;
      }
    }
    x4expL*=4;
  }
}

/**
 * @brief 计算基四FFT 双精度
 * @param h_fft h_fft对象
 * @param Src 源数据 计算结果也存放在此处
 * @return 无
 */
void H_FFT_cfftRadix4_Double(H_FFT *h_fft,double *Src){

  double* W;

  double* ArrDouble_t;

  //4^L
  int x4expL;
  int L;
  int L_m;
  int g;
  int g_m;
  int r;

  double* x0_ptr;
  double* x1_ptr;
  double* x2_ptr;
  double* x3_ptr;
  double x0_real;
  double x0_image;
  double x1_real;
  double x1_image;
  double x2_real;
  double x2_image;
  double x3_real;
  double x3_image;

  double t0_real;
  double t0_image;
  double t1_real;
  double t1_image;

  double W1_real;
  double W1_image;
  double W2_real;
  double W2_image;
  double W3_real;
  double W3_image;

  int NumOfPoint;
  int NumOfPointOf4;
  
  //为(r*(NumOfPointOf4/x4expL))*2
  int r_NumOfPointOf4__x4expL_2;


  if(h_fft->Type!=vH_FFT_Type_Single){
    return;
  }
  if(h_fft->Radix4_Enable==0){
    return;
  }
  
  NumOfPoint=h_fft->NumOfPoint;

  h_fft->ReverseData(h_fft,Src,NumOfPoint);

  NumOfPointOf4=NumOfPoint>>2;
  W=h_fft->W;
  

  x4expL=1;
  //蝶形运算 计算每一级
  L_m=h_fft->NumOfPointBits/2;
  for(L=0; L<L_m; L++){
    //蝶形一组的运算 循环每一组
    g_m=NumOfPointOf4/x4expL;
    for(g=0; g<g_m; g++){
      //每次循环计算一个基四蝶形运算
      for(r=0; r<x4expL; r++){

        //获取蝶形运算需要的源数据
        x0_ptr=&Src[(g*4*x4expL+r)*2];
        x2_ptr=&x0_ptr[x4expL*2];
        x1_ptr=&x2_ptr[x4expL*2];
        x3_ptr=&x1_ptr[x4expL*2];
        x0_real=x0_ptr[0];
        x0_image=x0_ptr[1];
        x1_real=x1_ptr[0];
        x1_image=x1_ptr[1];
        x2_real=x2_ptr[0];
        x2_image=x2_ptr[1];
        x3_real=x3_ptr[0];
        x3_image=x3_ptr[1];



        //获取旋转因数 W
        r_NumOfPointOf4__x4expL_2=(r*(NumOfPointOf4/x4expL))*2;
        ArrDouble_t=&W[r_NumOfPointOf4__x4expL_2];
        W1_real=ArrDouble_t[0];
        W1_image=ArrDouble_t[1];
        ArrDouble_t=&ArrDouble_t[r_NumOfPointOf4__x4expL_2];
        W2_real=ArrDouble_t[0];
        W2_image=ArrDouble_t[1];
        ArrDouble_t=&ArrDouble_t[r_NumOfPointOf4__x4expL_2];
        W3_real=ArrDouble_t[0];
        W3_image=ArrDouble_t[1];

        //计算 x1*W
        t0_real=x1_real*W1_real-x1_image*W1_image;
        t0_image=x1_real*W1_image+x1_image*W1_real;
        x1_real=t0_real;
        x1_image=t0_image;

        //计算 x2*W
        t0_real=x2_real*W2_real-x2_image*W2_image;
        t0_image=x2_real*W2_image+x2_image*W2_real;
        x2_real=t0_real;
        x2_image=t0_image;

        //计算 x3*W
        t0_real=x3_real*W3_real-x3_image*W3_image;
        t0_image=x3_real*W3_image+x3_image*W3_real;
        x3_real=t0_real;
        x3_image=t0_image;

        //计算中间值 U(0)->t0 U(2)->t1
        t0_real=x0_real+x2_real;
        t0_image=x0_image+x2_image;
        t1_real=x1_real+x3_real;
        t1_image=x1_image+x3_image;
        
        //计算蝶形结果 X(0)->Src[(g*4*x4expL+r)*2] X(1)->Src[(g*4*x4expL+r+x4expL*2)*2]
        x0_ptr[0]=t0_real+t1_real;
        x0_ptr[1]=t0_image+t1_image;
        x1_ptr[0]=t0_real-t1_real;
        x1_ptr[1]=t0_image-t1_image;

        //计算中间值 U(3)->t1
        t1_real=x1_image-x3_image;
        t1_image=x3_real-x1_real;

        //计算中间值 U(1)->t0
        t0_real=x0_real-x2_real;
        t0_image=x0_image-x2_image;

        //计算蝶形结果 X(2)->Src[(g*4*x4expL+r+x4expL)*2] X(3)->Src[(g*4*x4expL+r+x4expL*3)*2]
        x2_ptr[0]=t0_real+t1_real;
        x2_ptr[1]=t0_image+t1_image;
        x3_ptr[0]=t0_real-t1_real;
        x3_ptr[1]=t0_image-t1_image;
      }
    }
    x4expL*=4;
  }
}










